package com.qian.service.ddj.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.qian.api.ddj.model.CustomerChannel;
import com.qian.api.ddj.model.PayTypeDict;
import com.qian.api.ddj.model.StatusDict;
import com.qian.api.ddj.model.User;
import com.qian.api.ddj.service.IUserService;
import com.qian.service.ddj.dao.BusinessRepository;
import com.qian.service.ddj.dao.RechargeLogRepository;
import com.qian.service.ddj.dao.UserRepository;
import com.qian.service.ddj.entity.*;
import com.yaowk.api.common.BaseException;
import com.yaowk.api.utils.HttpUtils;
import com.yaowk.service.common.BaseRepository;
import com.yaowk.service.common.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.qian.service.ddj.Constant.*;

@Service("DdjUserServiceImpl")
public class UserServiceImpl extends BaseServiceImpl<User, DdjUser, Integer> implements IUserService {

    @Autowired
    private UserRepository dao;
    @Autowired
    private RechargeLogRepository rechargeDao;
    @Autowired
    private BusinessRepository businessDao;

    @Override
    protected BaseRepository<DdjUser, Integer> getDao() {
        return this.dao;
    }

    @Override
    protected DdjUser model2Entity(User user) {
        DdjUser ddjUser = null;
        if (!ObjectUtils.isEmpty(user)) {
            ddjUser = new DdjUser();
            ddjUser.setId(user.getId());
            ddjUser.setPassword(user.getPassword());
            ddjUser.setBalance(user.getBalance());
            ddjUser.setUsername(user.getUsername());
            ddjUser.setStatus(user.getStatus());
            ddjUser.setNotifyBalance(user.getNotifyBalance());
            ddjUser.setBalance(user.getBalance());
            ddjUser.setAutoCashBalance(user.getAutoCashBalance());
            ddjUser.setCardNo(user.getCardNo());
            ddjUser.setCardPerson(user.getCardPerson());
            ddjUser.setCardPhone(user.getCardPhone());
            ddjUser.setIsAutoCash(user.getIsAutoCash());
            ddjUser.setIsSend(user.getIsSend());
            ddjUser.setNotifyCycle(user.getNotifyCycle());
            ddjUser.setSecretKey(user.getSecretKey());
            ddjUser.setCreateTime(user.getCreateTime());
            ddjUser.setRemark(user.getRemark());
            ddjUser.setEmail(user.getEmail());
            ddjUser.setName(user.getName());
            ddjUser.setIdCard(user.getIdCard());
            ddjUser.setPhone(user.getPhone());
            ddjUser.setPublicKey(user.getPublicKey());
            ddjUser.setDfFee(user.getDfFee());
            ddjUser.setIsAutoDf(user.getIsAutoDf());
            if (isNotEmpty(user.getDfBusinessId())){
                DdjDfBusiness ddjDfBusiness = new DdjDfBusiness();
                ddjDfBusiness.setId(user.getDfBusinessId());
                ddjUser.setDdjDfBusiness(ddjDfBusiness);
            }
        }
        return ddjUser;
    }

    @Override
    protected User entity2model(DdjUser ddjUser) {
        User user = null;
        if (!ObjectUtils.isEmpty(ddjUser)) {
            user = new User();
            user.setBalance(ddjUser.getBalance());
            user.setId(ddjUser.getId());
            user.setUsername(ddjUser.getUsername());
            user.setStatus(ddjUser.getStatus());
            user.setNotifyBalance(ddjUser.getNotifyBalance());
            user.setBalance(ddjUser.getBalance());
            user.setAutoCashBalance(ddjUser.getAutoCashBalance());
            user.setCardNo(ddjUser.getCardNo());
            user.setCardPerson(ddjUser.getCardPerson());
            user.setCardPhone(ddjUser.getCardPhone());
            user.setIsAutoCash(ddjUser.getIsAutoCash());
            user.setIsSend(ddjUser.getIsSend());
            user.setNotifyCycle(ddjUser.getNotifyCycle());
            user.setSecretKey(ddjUser.getSecretKey());
            user.setCreateTime(ddjUser.getCreateTime());
            user.setRemark(ddjUser.getRemark());
            user.setEmail(ddjUser.getEmail());
            user.setName(ddjUser.getName());
            user.setPhone(ddjUser.getPhone());
            user.setIdCard(ddjUser.getIdCard());
            user.setLockMoney(ddjUser.getLockMoney());
            user.setPublicKey(ddjUser.getPublicKey());
            user.setIsAutoDf(ddjUser.getIsAutoDf());
            user.setDfFee(ddjUser.getDfFee());
            if (isNotEmpty(ddjUser.getDdjDfBusiness())){
                user.setDfBusinessId(ddjUser.getDdjDfBusiness().getId());
            }
        }
        return user;
    }

    @Transactional
    public void recharge(Integer id, BigDecimal money) {
        int result = dao.increaseBalance(id, money);
        if (result != 1) {
            throw new RuntimeException("更新失败");
        }
        DdjRechargeLog ddjRechargeLog = new DdjRechargeLog();
        ddjRechargeLog.setMoney(money);
        ddjRechargeLog.setUserId(id);
        rechargeDao.save(ddjRechargeLog);
    }

    public BigDecimal platformBalance() {
        Map<String, String> map = new HashMap<String, String>();
        String transDate = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        map.put("transDate", transDate);
        map.put("userid", USERID);
        String sign = String.format(BALANCE_TEMPLATE, transDate, USERID, KEY);
        sign = DigestUtils.md5DigestAsHex(sign.getBytes());
        /** 上送的值为 */
        map.put("sign", sign);
        map.put("orderCode", "mb_balance");
        String receive = HttpUtils.post(URL, HttpUtils.formatData(map));
        System.out.println(receive);
        Map<String, Object> result = JSON.parseObject(receive, Map.class);
        return new BigDecimal(result.get("balance").toString());
    }

    @Transactional
    public void businessEdit(Integer userId, List<Integer> bussinessIds) {
        DdjUser ddjUser = dao.findOne(userId);
        Set<DdjBusiness> ddjBusinessSet = new HashSet<>();
        ddjUser.setBusinesses(ddjBusinessSet);
        Set<Byte> payTypes = new HashSet<>();
        Set<Integer> groupIds = new HashSet<>();
        if (!CollectionUtils.isEmpty(bussinessIds)) {
            for (Integer id : bussinessIds) {
                DdjBusiness ddjBusiness = businessDao.findOne(id);
                verifyPayType(ddjBusiness, payTypes, groupIds);
                ddjBusinessSet.add(ddjBusiness);
            }
        }
        dao.save(ddjUser);
    }

    /**
     * 验证绑定商户支付方式是否重复
     *
     * @param ddjBusiness
     * @param payTypes
     * @param groupIds
     */
    private void verifyPayType(DdjBusiness ddjBusiness, Set<Byte> payTypes, Set<Integer> groupIds) {
        DdjBusinessGroup ddjBusinessGroup = ddjBusiness.getBusinessGroup();
        if (groupIds.contains(ddjBusinessGroup.getId())) {
            return;
        }
        groupIds.add(ddjBusinessGroup.getId());
        if (ddjBusinessGroup.getAllowAliCode().equals(StatusDict.NORMAL)) {
            if (payTypes.contains(PayTypeDict.ALI_CODE)) {
                throw new BaseException("支付宝扫码重复");
            }
            payTypes.add(PayTypeDict.ALI_CODE);
        }
        if (ddjBusinessGroup.getAllowAliWap().equals(StatusDict.NORMAL)) {
            if (payTypes.contains(PayTypeDict.ALI_WAP)) {
                throw new BaseException("支付宝wap重复");
            }
            payTypes.add(PayTypeDict.ALI_WAP);
        }
        if (ddjBusinessGroup.getAllowJd().equals(StatusDict.NORMAL)) {
            if (payTypes.contains(PayTypeDict.JD)) {
                throw new BaseException("京东支付重复");
            }
            payTypes.add(PayTypeDict.JD);
        }
        if (ddjBusinessGroup.getAllowQq().equals(StatusDict.NORMAL)) {
            if (payTypes.contains(PayTypeDict.QQ)) {
                throw new BaseException("QQ支付重复");
            }
            payTypes.add(PayTypeDict.QQ);
        }
        if (ddjBusinessGroup.getAllowQuickBank().equals(StatusDict.NORMAL)) {
            if (payTypes.contains(PayTypeDict.QUICK_BANK)) {
                throw new BaseException("银联快捷重复");
            }
            payTypes.add(PayTypeDict.QUICK_BANK);
        }
        if (ddjBusinessGroup.getAllowWxCode().equals(StatusDict.NORMAL)) {
            if (payTypes.contains(PayTypeDict.WX_CODE)) {
                throw new BaseException("微信扫码重复");
            }
            payTypes.add(PayTypeDict.WX_CODE);
        }
        if (ddjBusinessGroup.getAllowWxH5().equals(StatusDict.NORMAL)) {
            if (payTypes.contains(PayTypeDict.WX_H5)) {
                throw new BaseException("微信扫码重复");
            }
            payTypes.add(PayTypeDict.WX_H5);
        }
        if (ddjBusinessGroup.getAllowQqWap().equals(StatusDict.NORMAL)) {
            if (payTypes.contains(PayTypeDict.QQ_WAP)) {
                throw new BaseException("QQwap重复");
            }
            payTypes.add(PayTypeDict.QQ_WAP);
        }
        if (ddjBusinessGroup.getAllowCodeBank().equals(StatusDict.NORMAL)) {
            if (payTypes.contains(PayTypeDict.CODE_BANK)) {
                throw new BaseException("银联扫码重复");
            }
            payTypes.add(PayTypeDict.CODE_BANK);
        }

    }

    @Override
    public Set<CustomerChannel> findCustomerChannelById(Integer userId) {
        DdjUser ddjUser = dao.findOne(userId);
        Set<DdjBusiness> ddjBusinesses = ddjUser.getBusinesses();
        Set<CustomerChannel> channels = new HashSet<>();
        for (DdjBusiness ddjBusiness : ddjBusinesses) {
            DdjBusinessGroup ddjBusinessGroup = ddjBusiness.getBusinessGroup();
            if (ddjBusinessGroup.getAllowJd().equals(StatusDict.NORMAL)) {
                CustomerChannel channel = new CustomerChannel();
                channel.setChannel(ddjBusinessGroup.getName());
                channel.setD0(ddjBusinessGroup.getD0());
                channel.setD1(ddjBusinessGroup.getD1());
                channel.setT0(ddjBusinessGroup.getT0());
                channel.setT1(ddjBusinessGroup.getT1());
                channel.setType("京东支付");
                channel.setTariff(ddjBusinessGroup.tariff(PayTypeDict.JD));
                addCustomerChannel(channel, channels);
            }
            if (ddjBusinessGroup.getAllowQq().equals(StatusDict.NORMAL)) {
                CustomerChannel channel = new CustomerChannel();
                channel.setChannel(ddjBusinessGroup.getName());
                channel.setD0(ddjBusinessGroup.getD0());
                channel.setD1(ddjBusinessGroup.getD1());
                channel.setT0(ddjBusinessGroup.getT0());
                channel.setT1(ddjBusinessGroup.getT1());
                channel.setType("QQ钱包");
                channel.setTariff(ddjBusinessGroup.tariff(PayTypeDict.QQ));
                addCustomerChannel(channel, channels);
            }
            if (ddjBusinessGroup.getAllowQqWap().equals(StatusDict.NORMAL)) {
                CustomerChannel channel = new CustomerChannel();
                channel.setChannel(ddjBusinessGroup.getName());
                channel.setD0(ddjBusinessGroup.getD0());
                channel.setD1(ddjBusinessGroup.getD1());
                channel.setT0(ddjBusinessGroup.getT0());
                channel.setT1(ddjBusinessGroup.getT1());
                channel.setType("QQWAP");
                channel.setTariff(ddjBusinessGroup.tariff(PayTypeDict.QQ_WAP));
                addCustomerChannel(channel, channels);
            }
            if (ddjBusinessGroup.getAllowQuickBank().equals(StatusDict.NORMAL)) {
                CustomerChannel channel = new CustomerChannel();
                channel.setChannel(ddjBusinessGroup.getName());
                channel.setD0(ddjBusinessGroup.getD0());
                channel.setD1(ddjBusinessGroup.getD1());
                channel.setT0(ddjBusinessGroup.getT0());
                channel.setT1(ddjBusinessGroup.getT1());
                channel.setType("银联快捷");
                channel.setTariff(ddjBusinessGroup.tariff(PayTypeDict.QUICK_BANK));
                addCustomerChannel(channel, channels);
            }
            if (ddjBusinessGroup.getAllowCodeBank().equals(StatusDict.NORMAL)) {
                CustomerChannel channel = new CustomerChannel();
                channel.setChannel(ddjBusinessGroup.getName());
                channel.setD0(ddjBusinessGroup.getD0());
                channel.setD1(ddjBusinessGroup.getD1());
                channel.setT0(ddjBusinessGroup.getT0());
                channel.setT1(ddjBusinessGroup.getT1());
                channel.setType("银联扫码");
                channel.setTariff(ddjBusinessGroup.tariff(PayTypeDict.CODE_BANK));
                addCustomerChannel(channel, channels);
            }
            if (ddjBusinessGroup.getAllowWxH5().equals(StatusDict.NORMAL)) {
                CustomerChannel channel = new CustomerChannel();
                channel.setChannel(ddjBusinessGroup.getName());
                channel.setD0(ddjBusinessGroup.getD0());
                channel.setD1(ddjBusinessGroup.getD1());
                channel.setT0(ddjBusinessGroup.getT0());
                channel.setT1(ddjBusinessGroup.getT1());
                channel.setType("微信H5");
                channel.setTariff(ddjBusinessGroup.tariff(PayTypeDict.WX_H5));
                addCustomerChannel(channel, channels);
            }
            if (ddjBusinessGroup.getAllowWxCode().equals(StatusDict.NORMAL)) {
                CustomerChannel channel = new CustomerChannel();
                channel.setChannel(ddjBusinessGroup.getName());
                channel.setD0(ddjBusinessGroup.getD0());
                channel.setD1(ddjBusinessGroup.getD1());
                channel.setT0(ddjBusinessGroup.getT0());
                channel.setT1(ddjBusinessGroup.getT1());
                channel.setType("微信扫码");
                channel.setTariff(ddjBusinessGroup.tariff(PayTypeDict.WX_CODE));
                addCustomerChannel(channel, channels);
            }
            if (ddjBusinessGroup.getAllowAliWap().equals(StatusDict.NORMAL)) {
                CustomerChannel channel = new CustomerChannel();
                channel.setChannel(ddjBusinessGroup.getName());
                channel.setD0(ddjBusinessGroup.getD0());
                channel.setD1(ddjBusinessGroup.getD1());
                channel.setT0(ddjBusinessGroup.getT0());
                channel.setT1(ddjBusinessGroup.getT1());
                channel.setType("支付宝wap");
                channel.setTariff(ddjBusinessGroup.tariff(PayTypeDict.ALI_WAP));
                addCustomerChannel(channel, channels);
            }
            if (ddjBusinessGroup.getAllowAliCode().equals(StatusDict.NORMAL)) {
                CustomerChannel channel = new CustomerChannel();
                channel.setChannel(ddjBusinessGroup.getName());
                channel.setD0(ddjBusinessGroup.getD0());
                channel.setD1(ddjBusinessGroup.getD1());
                channel.setT0(ddjBusinessGroup.getT0());
                channel.setT1(ddjBusinessGroup.getT1());
                channel.setType("支付宝扫码");
                channel.setTariff(ddjBusinessGroup.tariff(PayTypeDict.ALI_CODE));
                addCustomerChannel(channel, channels);
            }
        }
        return channels;
    }

    private void addCustomerChannel(CustomerChannel customerChannel, Set<CustomerChannel> channels) {
        channels.add(customerChannel);
    }

    @Override
    @Transactional
    public User save(User model) {
        if (model.isNew()) {
            model = simpleSave(model);
        } else {
            DdjUser ddjUser = dao.findOne(model.getId());
            if (!ObjectUtils.isEmpty(model.getStatus())) {
                ddjUser.setStatus(model.getStatus());
            }
            if (!StringUtils.isEmpty(model.getPassword())) {
                ddjUser.setPassword(model.getPassword());
            }
            if (!StringUtils.isEmpty(model.getSecretKey())) {
                ddjUser.setSecretKey(model.getSecretKey());
            }
            if (!ObjectUtils.isEmpty(model.getAutoCashBalance())) {
                ddjUser.setAutoCashBalance(model.getAutoCashBalance());
            }
            if (!ObjectUtils.isEmpty(model.getCardNo())) {
                ddjUser.setCardNo(model.getCardNo());
            }
            if (!ObjectUtils.isEmpty(model.getCardPerson())) {
                ddjUser.setCardPerson(model.getCardPerson());
            }
            if (!ObjectUtils.isEmpty(model.getCardPhone())) {
                ddjUser.setCardPhone(model.getCardPhone());
            }
            if (!ObjectUtils.isEmpty(model.getPhone())){
                ddjUser.setPhone(model.getPhone());
            }
            if (!ObjectUtils.isEmpty(model.getIsAutoCash())) {
                ddjUser.setIsAutoCash(model.getIsAutoCash());
            }
            if (!ObjectUtils.isEmpty(model.getIsSend())) {
                ddjUser.setIsSend(model.getIsSend());
            }
            if (!ObjectUtils.isEmpty(model.getNotifyBalance())) {
                ddjUser.setNotifyBalance(model.getNotifyBalance());
            }
            if (!ObjectUtils.isEmpty(model.getNotifyCycle())) {
                ddjUser.setNotifyCycle(model.getNotifyCycle());
            }
            if (!ObjectUtils.isEmpty(model.getRemark())) {
                ddjUser.setRemark(model.getRemark());
            }
            if (!ObjectUtils.isEmpty(model.getPublicKey())){
                ddjUser.setPublicKey(model.getPublicKey());
            }
            if (!ObjectUtils.isEmpty(model.getIsAutoDf())){
                ddjUser.setIsAutoDf(model.getIsAutoDf());
            }
            if (isNotEmpty(model.getDfFee())){
                ddjUser.setDfFee(model.getDfFee());
            }
            if (isNotEmpty(model.getDfBusinessId())){
                DdjDfBusiness ddjDfBusiness = new DdjDfBusiness();
                ddjDfBusiness.setId(model.getDfBusinessId());
                ddjUser.setDdjDfBusiness(ddjDfBusiness);
            }
            model = entity2model(dao.save(ddjUser));
        }
        return model;
    }

    @Override
    @Transactional
    public void lockMoney(Integer userId, BigDecimal money) {
        dao.lockMoney(userId, money);
    }

    @Override
    @Transactional
    public void unLockMoney(Integer userId, BigDecimal money) {
        dao.unLockMoney(userId, money);
    }
}
